package org.kia.activity;

/*
 * Copyright (C) 2010 The Android Open Source Project
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 *      http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */

import java.util.ArrayList;
import java.util.List;

import org.kia.R;
import org.kia.activity.adapters.BusinessSearchListAdapter;
import org.kia.activity.adapters.SearchListAdapter;
import org.kia.activity.interfaces.SearchActivityInterface;
import org.kia.activity.interfaces.SearchCategoriesInterface;
import org.kia.activity.interfaces.SearchItemsInterface;
import org.kia.data.model.CategoryModel;
import org.kia.data.model.ItemModel;
import org.kia.manager.SearchManager;

import android.content.Context;
import android.content.Intent;
import android.content.res.Configuration;
import android.os.Bundle;
import android.support.v4.app.FragmentActivity;
import android.support.v4.app.FragmentTransaction;
import android.support.v4.app.ListFragment;
import android.view.View;
import android.widget.ListView;

/**
 * Demonstration of using fragments to implement different activity layouts. This sample provides a different layout
 * (and activity flow) when run in landscape.
 */
public class FragmentSearchActivity extends FragmentActivity implements SearchActivityInterface {

	private static SearchManager mManager = SearchManager.getInstance();

	@Override
	protected void onCreate(Bundle savedInstanceState) {
		super.onCreate(savedInstanceState);

		setContentView(R.layout.search_fragments_main);
		mManager.onActivityReady(this);
	}

	@Override
	public Context getContext() {
		return this;
	}

	/**
	 * This is a secondary activity, to show what the user has selected when the screen is not large enough to show it
	 * all in one activity.
	 */
	public static class ItemsInCategoryActivity extends FragmentActivity {

		@Override
		protected void onCreate(Bundle savedInstanceState) {
			super.onCreate(savedInstanceState);

			if (getResources().getConfiguration().orientation == Configuration.ORIENTATION_LANDSCAPE) {
				// If the screen is now in landscape mode, we can show the
				// dialog in-line with the list so we don't need this activity.
				finish();
				return;
			}

			if (savedInstanceState == null) {
				// During initial setup, plug in the details fragment.
				ItemsInCategoryFragment details = new ItemsInCategoryFragment();
				details.setArguments(getIntent().getExtras());
				getSupportFragmentManager().beginTransaction().add(android.R.id.content, details).commit();
			}
		}
	}

	/**
	 * This is the "top-level" fragment, showing a list of categories that the user can pick. Upon picking an item, it
	 * takes care of displaying the data to the user as appropriate based on the current UI layout.
	 */
	public static class CategoriesFragment extends ListFragment implements SearchCategoriesInterface {

		static final String EXTRA_CURRENT_MODEL_ID = "current_model";
		static final String EXTRA_CURRENT_SELECTED_POSITION = "current_selected_position";
		private final String EXTRA_CURRENT_MODELS = "current_models";

		private boolean mDualPane;
		private String mCurrentModelId;
		private int mCurrentSelectedPosition;

		@Override
		public void onActivityCreated(Bundle savedInstanceState) {
			super.onActivityCreated(savedInstanceState);
			
			init(savedInstanceState);
			mManager.onCategoriesReady(this);
		}
		
		@Override
		public void onDestroyView() {
			super.onDestroyView();
			mManager.onCategoryDistroyed();
		}

		/**
		 * Initialization sequence
		 * 
		 * @param savedInstanceState
		 */
		private void init(Bundle savedInstanceState) {
			SearchListAdapter<CategoryModel> adapter = new SearchListAdapter<CategoryModel>(getActivity());
			setListAdapter(adapter);

			// Check to see if we have a frame in which to embed the ItemsInCategory
			// fragment directly in the containing UI.
			View ItemsInCategoryFrame = getActivity().findViewById(R.id.search_List_items);
			mDualPane = ((ItemsInCategoryFrame != null) && (ItemsInCategoryFrame.getVisibility() == View.VISIBLE));

			if (savedInstanceState != null) {
				// Restore last state for checked position.
				mCurrentModelId = savedInstanceState.getString(EXTRA_CURRENT_MODEL_ID);
				mCurrentSelectedPosition = savedInstanceState.getInt(EXTRA_CURRENT_SELECTED_POSITION, 0);
				List<CategoryModel> data = savedInstanceState.getParcelableArrayList(EXTRA_CURRENT_MODELS);
				if (data != null) {
					setCategories(data, false);
				}
				
				if (mDualPane) {
					// Make sure our UI is in the correct state.
					showItemsInCategory(mCurrentSelectedPosition, mCurrentModelId);
				}
			} 

			if (mDualPane) {
				// In dual-pane mode, the list view highlights the selected item.
				getListView().setChoiceMode(ListView.CHOICE_MODE_SINGLE);
			}
		}

		@Override
		public void onSaveInstanceState(Bundle outState) {
			super.onSaveInstanceState(outState);
			outState.putString(EXTRA_CURRENT_MODEL_ID, mCurrentModelId);
			outState.putInt(EXTRA_CURRENT_SELECTED_POSITION, mCurrentSelectedPosition);
			outState.putParcelableArrayList(EXTRA_CURRENT_MODELS,
					(ArrayList<CategoryModel>) ((SearchListAdapter) getListAdapter()).getData());
		}

		@Override
		public void onListItemClick(ListView l, View v, int position, long id) {
			showItemsInCategory(position, ((CategoryModel) l.getItemAtPosition(position)).getModelId());
		}

		@Override
		@SuppressWarnings({ "unchecked", "rawtypes" })
		public void setCategories(List<CategoryModel> data) {
			setCategories(data, true);
		}
		
		public void setCategories(List<CategoryModel> data, boolean showItems) {
			((SearchListAdapter) getListAdapter()).setData(data);
			if (showItems && mDualPane && data != null && data.size() > 0) {
				showItemsInCategory(0, data.get(0).getModelId());
			}
		}

		/**
		 * Helper function to show the items of a selected category, either by displaying a fragment in-place in the
		 * current UI, or starting a whole new activity in which it is displayed.
		 */
		void showItemsInCategory(int index, String modelId) {
			mCurrentSelectedPosition = index;
			mCurrentModelId = modelId;

			if (mDualPane) {
				// We can display everything in-place with fragments, so update
				// the list to highlight the selected item and show the data.
				getListView().setItemChecked(index, true);

				// Check what fragment is currently shown, replace if needed.
				ItemsInCategoryFragment items = (ItemsInCategoryFragment) getFragmentManager().findFragmentById(
						R.id.search_List_items);
				if (items == null || items.getShownIndex() != index) {
					// Make new fragment to show this selection.
					items = ItemsInCategoryFragment.newInstance(index, modelId);

					// Execute a transaction, replacing any existing fragment
					// with this one inside the frame.
					FragmentTransaction ft = getFragmentManager().beginTransaction();
					ft.replace(R.id.search_List_items, items);
					ft.setTransition(FragmentTransaction.TRANSIT_FRAGMENT_FADE);
					ft.commit();
				}
			} else {
				// Otherwise we need to launch a new activity to display
				// the dialog fragment with selected text.
				Intent intent = new Intent();
				intent.setClass(getActivity(), ItemsInCategoryActivity.class);
				intent.putExtra(EXTRA_CURRENT_MODEL_ID, mCurrentModelId);
				intent.putExtra(EXTRA_CURRENT_SELECTED_POSITION, index);
				startActivity(intent);
			}
		}
	}

	/**
	 * This is the secondary fragment, displaying the details of a particular item.
	 */
	public static class ItemsInCategoryFragment extends ListFragment implements SearchItemsInterface {

		/**
		 * Create a new instance of DetailsFragment, initialized to show the text at 'index'.
		 */
		public static ItemsInCategoryFragment newInstance(int index, String modelId) {
			ItemsInCategoryFragment f = new ItemsInCategoryFragment();
				
			// Supply index input as an argument.
			Bundle args = new Bundle();
			args.putInt(CategoriesFragment.EXTRA_CURRENT_SELECTED_POSITION, index);
			args.putString(CategoriesFragment.EXTRA_CURRENT_MODEL_ID, modelId);
			f.setArguments(args);

			return f;
		}

		/**
		 * get the index of the selected shown {@link CategoriesFragment}
		 * 
		 * @return
		 */
		public int getShownIndex() {
			return getArguments().getInt(CategoriesFragment.EXTRA_CURRENT_SELECTED_POSITION, 0);
		}

		/**
		 * Get selected shown {@link CategoriesFragment}
		 * 
		 * @return
		 */
		public String getModelId() {
			return getArguments().getString(CategoriesFragment.EXTRA_CURRENT_MODEL_ID);
		}
		
		@Override
		public void onSaveInstanceState(Bundle outState) {
			super.onSaveInstanceState(outState);
			outState.putString(CategoriesFragment.EXTRA_CURRENT_MODEL_ID, getModelId());
			outState.putInt(CategoriesFragment.EXTRA_CURRENT_SELECTED_POSITION, getShownIndex());
		}
		
		@Override
		public void onActivityCreated(Bundle savedInstanceState) {
			super.onActivityCreated(savedInstanceState);
			BusinessSearchListAdapter adapter = new BusinessSearchListAdapter(getActivity());
			setListAdapter(adapter);
			
//			if (savedInstanceState != null) {
//				// Update our arguments (why do we use arguments?)
//				Bundle args = new Bundle();
//				args.putInt(CategoriesFragment.EXTRA_CURRENT_SELECTED_POSITION, savedInstanceState.getInt(CategoriesFragment.EXTRA_CURRENT_MODEL_ID, 0));
//				args.putString(CategoriesFragment.EXTRA_CURRENT_MODEL_ID, savedInstanceState.getString(CategoriesFragment.EXTRA_CURRENT_SELECTED_POSITION));
//				setArguments(args);
//			}
			
			mManager.onItemsReady(this, getModelId());
		}

		@Override
		public void setItems(List<ItemModel> data) {
			((BusinessSearchListAdapter) getListAdapter()).setData(data);
		}
		
		@Override
		public void onDestroyView() {
			super.onDestroyView();
			mManager.onItemsDistroyed();
		}
		

//		@Override
//		public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) {
//			if (container == null) {
//				// We have different layouts, and in one of them this
//				// fragment's containing frame doesn't exist. The fragment
//				// may still be created from its saved state, but there is
//				// no reason to try to create its view hierarchy because it
//				// won't be displayed. Note this is not needed -- we could
//				// just run the code below, where we would create and return
//				// the view hierarchy; it would just never be used.
//				return null;
//			}
//			mManager.onItemsReady(this);
//			
//			if (savedInstanceState != null) {
//				// Update our arguments (why do we use arguments?)
//				Bundle args = new Bundle();
//				args.putInt(CategoriesFragment.EXTRA_CURRENT_SELECTED_POSITION, savedInstanceState.getInt(CategoriesFragment.EXTRA_CURRENT_MODEL_ID));
//				args.putString(CategoriesFragment.EXTRA_CURRENT_MODEL_ID, savedInstanceState.getString(CategoriesFragment.EXTRA_CURRENT_SELECTED_POSITION));
//				setArguments(args);
//			}
//			
//			
//			ScrollView scroller = new ScrollView(getActivity());
//			TextView text = new TextView(getActivity());
//			int padding = (int) TypedValue.applyDimension(TypedValue.COMPLEX_UNIT_DIP, 4, getActivity().getResources()
//					.getDisplayMetrics());
//			text.setPadding(padding, padding, padding, padding);
//			scroller.addView(text);
//			text.setText(getModelId());
//
//			return scroller;
//		}
	}

}